package org.zjvis.datascience.web.controller;

import cn.weiguangfu.swagger2.plus.annotation.ApiPlus;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.zjvis.datascience.common.annotation.RoleCheck;
import org.zjvis.datascience.common.dto.AuditDTO;
import org.zjvis.datascience.common.dto.AuditQueryDTO;
import org.zjvis.datascience.common.dto.DatasetsTotalInfo;
import org.zjvis.datascience.common.dto.OperatorTemplateDTO;
import org.zjvis.datascience.common.dto.user.AdminSelectResDTO;
import org.zjvis.datascience.common.dto.user.QueryFeedbackDTO;
import org.zjvis.datascience.common.dto.user.UserDTO;
import org.zjvis.datascience.common.dto.user.UserDataInfoDTO;
import org.zjvis.datascience.common.dto.user.UserFeedbackDTO;
import org.zjvis.datascience.common.dto.user.UserInfoDTO;
import org.zjvis.datascience.common.enums.NoticeTypeEnum;
import org.zjvis.datascience.common.enums.TaskTypeEnum;
import org.zjvis.datascience.common.exception.BaseErrorCode;
import org.zjvis.datascience.common.exception.DataScienceException;
import org.zjvis.datascience.common.model.ApiResult;
import org.zjvis.datascience.common.model.ApiResultCode;
import org.zjvis.datascience.common.util.DozerUtil;
import org.zjvis.datascience.common.util.JwtUtil;
import org.zjvis.datascience.common.vo.AuditQueryVO;
import org.zjvis.datascience.common.vo.FeedbackQueryVO;
import org.zjvis.datascience.common.vo.OperatorTemplateVO;
import org.zjvis.datascience.common.vo.TaskInstancePageVO;
import org.zjvis.datascience.common.vo.UserSelectVO;
import org.zjvis.datascience.common.vo.notice.FeedbackNoticeAddVO;
import org.zjvis.datascience.common.vo.user.UserRoleVO;
import org.zjvis.datascience.service.AdminService;
import org.zjvis.datascience.service.NoticeService;
import org.zjvis.datascience.service.OperatorTemplateService;
import org.zjvis.datascience.service.TaskInstanceService;
import org.zjvis.datascience.service.audit.AuditService;

/**
 * @description 管理员 Controller
 * @date 2021-09-18
 */
@ApiPlus(value = true)
@RestController
@RequestMapping("/admin")
@RoleCheck
@Api(tags = "admin", description = "管理员相关接口")
@Validated
public class AdminController {

    @Autowired
    private OperatorTemplateService operatorTemplateService;

    @Autowired
    private AuditService auditService;

    @Autowired
    private AdminService adminService;

    @Autowired
    private TaskInstanceService taskInstanceService;

    @Lazy
    @Autowired
    private NoticeService noticeService;

    @PostMapping(value = "/queryOperator")
    @ResponseBody
    @ApiOperation(value = "根据算子状态查询用户自定义算子列表")
    public ApiResult<List<OperatorTemplateDTO>> queryByStatus(HttpServletRequest request, @RequestBody OperatorTemplateVO vo) {
        List<OperatorTemplateDTO> res = operatorTemplateService.queryByStatus(vo.getStatus());
        return ApiResult.valueOf(res);
    }

    @PostMapping(value = "/approveOperator")
    @ResponseBody
    @ApiOperation(value = "审核算子（通过/驳回/置为无效）")
    public ApiResult<Boolean> updateStatus(HttpServletRequest request, @RequestBody OperatorTemplateVO vo) {
        OperatorTemplateDTO dto = new OperatorTemplateDTO();
        dto.setSuggestion(vo.getSuggestion());
        dto.setStatus(vo.getStatus());
        dto.setId(vo.getId());
        return ApiResult.valueOf(operatorTemplateService.update(dto));
    }

    @PostMapping(value = "/audit")
    @ResponseBody
    @ApiOperation(value = "分页查看审计结果")
    public ApiResult<PageInfo<AuditDTO>> queryAuditDTO(HttpServletRequest request, @RequestBody AuditQueryVO vo) {
        PageInfo<AuditDTO> res = auditService.queryAuditByPage(DozerUtil.mapper(vo, AuditQueryDTO.class));
        return ApiResult.valueOf(res);
    }

    
    @PostMapping(value = "/selectFeedbacks")
    @ResponseBody
    @ApiOperation(value = "筛选条件查看用户反馈列表")
    public ApiResult<PageInfo<UserFeedbackDTO>>queryFeedbacks(HttpServletRequest request, @RequestBody FeedbackQueryVO vo) {
        PageInfo<UserFeedbackDTO> res = adminService.selectFeedbacks(DozerUtil.mapper(vo, QueryFeedbackDTO.class));
        return ApiResult.valueOf(res);
    }

    @PostMapping(value = "/queryOperatorDetail")
    @ResponseBody
    @ApiOperation(value = "自定义算子加载", notes = "自定义算子加载")
    public ApiResult<OperatorTemplateVO> loadDetail(HttpServletRequest request, @RequestBody OperatorTemplateVO vo) {
        OperatorTemplateDTO dto = null;
        if (vo.getId() == null) {
            return ApiResult.valueOf(ApiResultCode.PARAM_ERROR);
        } else {
            dto = operatorTemplateService.queryById(vo.getId());
        }
        if (dto == null) {
            return ApiResult.valueOf(ApiResultCode.SYS_ERROR);
        }
        return ApiResult.valueOf(dto.view());
    }

    @PostMapping(value = "/queryAllUserDTO")
    @ApiOperation(value = "根据用户名搜索所有满足条件的用户信息")
    public ApiResult<AdminSelectResDTO> queryAllUserDTO(@RequestBody UserSelectVO userSelectVO) {
        JSONObject jo = adminService.selectAllUserInfo(userSelectVO);
        int code = jo.getInteger("code");
        if (code != ApiResultCode.SUCCESS.getCode()) {
            return ApiResult.valueOf(ApiResultCode.DATA_NULL, null, jo.getString("errMsg"));
        }
        List<UserInfoDTO> userInfoDTOS = (List<UserInfoDTO>) jo.get("data");
        AdminSelectResDTO res = new AdminSelectResDTO<UserInfoDTO>(jo.getInteger("pageNum"), userInfoDTOS);
        return ApiResult.valueOf(DozerUtil.mapper(res, AdminSelectResDTO.class));
    }

    @PostMapping(value = "/queryAllUserDataSetDTO")
    @ApiOperation(value = "搜索所有满足条件的用户及其拥有的数据集信息")
    public ApiResult<AdminSelectResDTO> queryAllUserDataSetDTO(@RequestBody UserSelectVO userSelectVO) {
        JSONObject jo = adminService.selectAllUserDataSetInfo(userSelectVO);
        int code = jo.getInteger("code");
        if (code != ApiResultCode.SUCCESS.getCode()) {
            return ApiResult.valueOf(ApiResultCode.DATA_NULL, null, jo.getString("errMsg"));
        }
        List<UserDataInfoDTO> userDataInfoDTOS = (List<UserDataInfoDTO>) jo.get("data");
        AdminSelectResDTO res = new AdminSelectResDTO<UserDataInfoDTO>(jo.getInteger("pageNum"), userDataInfoDTOS);
        return ApiResult.valueOf(DozerUtil.mapper(res, AdminSelectResDTO.class));
    }

    @PostMapping(value = "/queryDataInfoById")
    @ApiOperation(value = "搜索某个用户的所有数据表信息")
    public ApiResult<DatasetsTotalInfo> queryDataInfoById(Long userId) {
        JSONObject result = adminService.queryDatasetInfoByUserId(userId);
        int code = result.getInteger("code");
        if (code == ApiResultCode.SYS_ERROR.getCode()) {
            return ApiResult.valueOf(ApiResultCode.SYS_ERROR, null, result.getString("errMsg"));
        }

        DatasetsTotalInfo datasetsTotalInfo = (DatasetsTotalInfo) result.get("data");
        if (datasetsTotalInfo.getTableCnt() == 0) {
            return ApiResult.valueOf(ApiResultCode.DATASET_INFO_NULL, null, "不存在数据表");
        }
        return ApiResult.valueOf(DozerUtil.mapper(datasetsTotalInfo, DatasetsTotalInfo.class));
    }

    @PostMapping(value = "/selectLikeDataName")
    @ApiOperation(value = "模糊搜索满足条件的数据集名")
    public ApiResult<List<String>> selectLikeDataName(String datasetName) {
        return ApiResult.valueOf(adminService.selectLikeDataName(datasetName));
    }

    @PostMapping(value = "/queryFeedbackById")
    @ApiOperation(value = "根据某个反馈的id搜索全部反馈信息")
    public ApiResult<UserFeedbackDTO> queryFeedbackById(Long id) {
        UserFeedbackDTO user = adminService.queryById(id);
        String pics=user.getFeedbackPic();
        user.setFeedbackPicList(Arrays.asList(pics.split("\\|")));
        return ApiResult.valueOf(DozerUtil.mapper(user, UserFeedbackDTO.class));
    }

    @PostMapping(value = "/queryTaskInstanceInfo")
    @ApiOperation(value = "获取task instance信息")
    public ApiResult<Object> queryTaskInstanceInfo(@RequestBody TaskInstancePageVO vo) {
        return ApiResult.valueOf(taskInstanceService.queryTaskInstancePageInfo(vo));
    }

    @PostMapping(value = "/queryTaskType")
    @ApiOperation(value = "获取任务操作类型")
    public ApiResult<Object> queryTaskType() {
        TaskTypeEnum[] values = TaskTypeEnum.values();
        JSONArray ja = new JSONArray();
        for (TaskTypeEnum value:values) {
            JSONObject jo = new JSONObject();
            jo.put("type",value.getVal());
            jo.put("typeName",value.getDesc());
            ja.add(jo);
        }
        return ApiResult.valueOf(ja);
    }

    @PostMapping(value = "/adminSetRole")
    @ResponseBody
    @ApiOperation(value = "添加/删除管理员权限")
    public ApiResult<Boolean> adminSetRole(@RequestBody UserRoleVO userRoleVo) {
        UserDTO user = DozerUtil.mapper(userRoleVo, UserDTO.class);
        return ApiResult.valueOf(adminService.updateUserRole(user));
    }

    @PostMapping(value = "/sendNotice")
    @ApiOperation(value = "发送消息")
    @Transactional
    public ApiResult<Boolean> sendNotice(@Valid @RequestBody FeedbackNoticeAddVO vo) {
        UserFeedbackDTO feedback = adminService.queryById(vo.getId());
        if (feedback==null||!feedback.getUserId().equals(vo.getUserId())){
            throw new DataScienceException(BaseErrorCode.FEEDBACK_PARAMETER_NOT_MATCHING);
        } else if(feedback.getStatus()==1){
            throw new DataScienceException(BaseErrorCode.FEEDBACK_NOTICE_REPEAT_SEND);
        }
        int res = adminService.updateFeedbackStatus(vo);
        if (res>0) {
            noticeService.saveAndSendToUser(vo.getUserId(),vo.getTitle(), vo.getContent(),
                NoticeTypeEnum.system.getType(), JwtUtil.getCurrentUserId());
        } else {
            throw new DataScienceException(BaseErrorCode.FEEDBACK_NOTICE_REPEAT_SEND);
        }

        return ApiResult.valueOf(true);
    }
}
